# -*- coding:utf-8 -*-
"""
@Author : 审心
@Time : 2023/3/30 9:02
获取竞品关键词相关代码
"""
import random
import re
import shutil
import sys
import time
from dataclasses import dataclass
from typing import Optional, List, Union

import xlwings as xw

from DrissionPage import WebPage
from xlwings import Book

from autoTask.taobao.sycm.gjc.competitorGoodKey.getCompetingKeyAction.AppendXgfxDataAction import AppendXgfxDataAction
from autoTask.taobao.sycm.gjc.competitorGoodKey.getCompetingKeyAction.getContrastData import GetContrastData
from autoTask.taobao.sycm.gjc.competitorGoodKey.getCompetingKeyAction.setCompetingProductsConfigAction import \
    SetCompetingProductsConfigAction
from autoTask.taobao.sycm.gjc.competitorGoodKey.publicResource import __links as links, wait_tb_complete, \
    MonitorCompetingProduct, get_xws_copy_action_content, GoodsFeature
from common.utils import FileUtil, ExcelUtil, ObjUtil, urlUtil, StrUtil
from common.utils.web_page_util import MockTap, wait_ele_text_range, ActionChain, Input, Tap
from common.logger.log import log_


def get_data_source_dev():
    """
    :return:
    """
    root = FileUtil.get_project_root()
    return FileUtil.read_file_contents([
        root + r"/taskTemplateExcel/dev/gjc/test/competitorGoodKey/关键指标对比.txt",
        root + r"/taskTemplateExcel/dev/gjc/test/competitorGoodKey/入店来源.txt",
        root + r"/taskTemplateExcel/dev/gjc/test/competitorGoodKey/多天搜索成交关键词.txt",
    ])


@dataclass
class GetCompetingKey:
    """
    获取竞品关键词
    :param page: 网页对象
    :param target_goods: {'category':平底锅,'my':1,'competing1':2,'competing2':3}
    :param ignore_keys 包含此列表中内容的关键词移除
    :param key_is_not_contain_letter 关键词中是否包含字母
    :param temp_tb 任务所需的临时表格
    :param competing_min_visits 竞争关键词最低访问数
    :param competing_min_roi 竞争关键词最低 roi (百分比 : 10.20)
    :param is_return_excel_path 是否返回结果表格路径
    :param is_test_execute 是否测试执行
    """
    page: WebPage
    target_goods: dict[str, list[GoodsFeature]]
    ignore_keys: list[str]
    key_is_not_contain_letter: bool = False
    temp_tb: Optional[Book] = None
    competing_min_visits: int = 0
    competing_min_roi: float = 0
    is_return_excel_path: bool = False
    is_test_execute: bool = False

    def __call__(self) -> Union[None, list[str], str]:
        """
        执行本流程
        :return: 返回任务结果附件路径(若结果附件没有生成则返回None)
        若 is_return_excel_path 为 true 则返回结果表格文件路径列表 不进行压缩
        """
        # 获取结果表格路径
        result_path = FileUtil.get_project_root() + r"\taskTemplateExcel\gjc\competitorGoodKey\result"
        # 清空结果表格
        FileUtil.clear_folder(result_path)
        # 生成临时表格
        self.create_temp_tb()
        # 按品类进行分组
        for category, values in self.target_goods.items():
            result_book = xw.Book()
            for item in values:
                log_.info(f"轮询到品类 : {category} 竞品映射 : {item}")
                # 设置本店竞品监控
                SetCompetingProductsConfigAction(self.page, (item.competing1, item.competing2))()
                # 获取竞品对比数据
                content = GetContrastData(self.page, item)()
                if ObjUtil.is_empty(content):
                    continue
                self.handle_td_data(content[0], content[1], content[2])
                # 将分析结果追加到新的结果页
                self.append_data_to_result_tb(result_book, item.goods_id, item.date_cycle)
                # 清理网页缓存刷新
                self.page.clear_cache(cookies=False)
                self.page.refresh()
            # 以上操作有追加新的 sheet 页才算成功才会保存表格
            if result_book.sheets.count > 1:
                result_book.sheets["Sheet1"].delete()
                result_book.save(result_path + fr"\{category}.xlsx")
            result_book.close()
        self.temp_tb.close()
        if FileUtil.count_files(result_path) == 0:
            log_.warning(f"GetCompetingKey -> 任务没有输出任何附件 : {self}")
            return None
        if self.is_return_excel_path:
            return FileUtil.get_all_files_in_folder(result_path)
        return FileUtil.zip_folder(result_path, result_path + r"/竞争对手好词.zip")

    def create_temp_tb(self):
        """
        创建临时模板表格
        :return:
        """
        if self.temp_tb is None:
            # 复制一份模板
            root_path = FileUtil.get_project_root()
            source_path = root_path + r"\taskTemplateExcel\gjc\competitorGoodKey\关键词2竞品分析-模板.xlsx"
            target_path = root_path + r"\taskTemplateExcel\gjc\competitorGoodKey\临时模板.xlsx"
            shutil.copy2(source_path, target_path)
            log_.info("1.复制任务表格模板成功")
            # 打开模板
            self.temp_tb = xw.Book(target_path)

    def handle_td_data(self, content1: str, content2: str, content3: str):
        """
        处理表格数据
        :param content1: 1-5-1-核心数据指标对比 需求数据
        :param content2: 1-5-2-流量结构对比 需求数据
        :param content3: 1-5-4关键词-原始数据 需求数据
        :return: 临时模板表格对象
        """
        # 前两项不重要
        # 到关键指标页面粘贴数据
        # ExcelUtil.xw_paste_content_to_sheet(self.temp_tb.sheets['1-5-1-核心数据指标对比'], content1, 'C1',
        #                                     clear_scope='C:Q')
        # log_.info("处理 1-5-1-核心数据指标对比 页成功")
        # 到流量结构对比页面粘贴数据
        # ExcelUtil.xw_paste_content_to_sheet(self.temp_tb.sheets['1-5-2-流量结构对比'], content2, 'C1',
        #                                     clear_scope='C:L')
        # log_.info("处理 1-5-2-流量结构对比 页成功")
        # 到关键词 袁术数据页面粘贴数据
        sht = self.temp_tb.sheets['1-5-4关键词-原始数据']
        use_row = ExcelUtil.xw_get_has_content_row(sht, "L")
        ExcelUtil.xw_paste_content_to_sheet(sht, content3, 'L2', clear_scope=f'L2:T{use_row}')
        use_row = ExcelUtil.xw_get_has_content_row(sht, "L")
        ExcelUtil.xw_autofill_sheet(sht, f'A1:K{use_row}', clear_scope=f"A2:k{use_row}")
        log_.info("处理 1-5-4关键词-原始数据 页成功")
        # 处理结果数据 (1-5-3关键词对比) 数据
        # 1. 获取有效数据列
        effective_row = ExcelUtil.xw_find_last_nonzero_row(sht, "F", 0)
        # 2.重新格式化计算数据
        use_row = ExcelUtil.xw_get_has_content_row(sht, "A")
        sht = self.temp_tb.sheets['1-5-3关键词对比']
        ExcelUtil.xw_autofill_sheet(sht, f'A4:J{effective_row + 3}',
                                    clear_scope=f'A5:J{use_row}')
        log_.info("处理 1-5-3关键词对比 页成功")

    def append_data_to_result_tb(self, result_book: Book, new_sheet_name, date_cycle: str):
        """
        对结果表格追加数据
        :param date_cycle: 数据周期 7天 或 30天
        :param result_book: 结果表格 Book 对象
        :param new_sheet_name: 新 sheet 页名称
        :return:
        """

        def delete_data_condition(row):
            """
            删除指定行数据的条件
            :param row: 当前行
            :return: true 删除
            """
            # 数据为空
            if ObjUtil.has_none([row[i] for i in [0, 4, 7, 6, 9]]):
                return True
            # 删除关键词包含指定字符的行
            if any(re.search(val, str(row[0])) for val in self.ignore_keys):
                return True
            if self.key_is_not_contain_letter and StrUtil.is_contain_letter(row[0]):
                return True
            # 删除不满足数据要求的行 由于两个竞品都在一行 所以一行的两个竞品都不满足才删除
            flag1 = row[4] < self.competing_min_visits or row[6] < self.competing_min_roi
            flag2 = row[7] < self.competing_min_visits or row[9] < self.competing_min_roi
            if flag1 and flag2:
                return True
            return False

        # 追加新 sheet
        result_sheet = ExcelUtil.xw_add_sheet_with_unique_name(result_book, new_sheet_name)
        # 获取数据源 sheet
        source_sheet = self.temp_tb.sheets["1-5-3关键词对比"]
        # 获取有数据的行数
        use_row = ExcelUtil.xw_get_has_content_row(source_sheet, "A")
        # 复制 sheet 值
        ExcelUtil.xw_copy_sheet_value(self.temp_tb.sheets['1-5-3关键词对比'], result_sheet
                                      , f"A2:J{use_row}", f"A1:J{use_row - 1}")
        # 洗数据
        ExcelUtil.xw_delete_rows_containing_values_v2(result_sheet, f'A3:J{use_row - 1}', delete_data_condition)
        # 设置一些列为百分比数值
        use_row = ExcelUtil.xw_get_has_content_row(result_sheet, "A")
        ExcelUtil.xw_format_ranges_as(result_sheet, f"D3:D{use_row},G3:G{use_row},J3:J{use_row}", "0.00%")
        # 补充结果数据
        AppendXgfxDataAction(sheet=result_sheet, date_cycle=date_cycle, p=self.page)()
